home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2001 / MacHack 2001.toast / pc / The Hacks / PhaseShiftX / Source / SillyBalls / balls.m < prev    next >
Encoding:
Text File  |  2001-06-23  |  3.5 KB  |  145 lines

  1. #import "balls.h"
  2.  
  3.  
  4. @implementation balls
  5. - (void)awakeFromNib
  6. {
  7.     if ([[self superclass] instancesRespondToSelector:@selector(awakeFromNib)])
  8.         [super awakeFromNib];
  9.     
  10.     [NSApp setDelegate:self];
  11. }
  12.  
  13.  
  14.  
  15. - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
  16. {
  17.     mRunning = NO;
  18.     
  19.     mWindow = [[NSWindow alloc] initWithContentRect:[[NSScreen mainScreen] frame]
  20.                 styleMask:NSBorderlessWindowMask
  21.                 backing:NSBackingStoreBuffered
  22.                 defer:NO];
  23.     
  24.     [mWindow setCanHide:NO];
  25.     [mWindow makeFirstResponder:self];
  26.     [mWindow setAutodisplay:YES];
  27.     [mWindow setContentView:self];
  28.     [mWindow setDelegate:self];
  29.     [mWindow setExcludedFromWindowsMenu:YES];
  30.     [mWindow setHasShadow:NO];
  31.     [mWindow useOptimizedDrawing:YES];
  32.     
  33.     [mWindow setBackgroundColor:[NSColor blackColor]];
  34.     [mWindow setLevel:kCGDesktopWindowLevel];
  35.     
  36.     [mWindow orderBack:self];
  37.     [self setTimerInterval:.05 source:NULL];
  38. }
  39.  
  40.  
  41.  
  42. - (void)setTimerRunning:(BOOL)run source:(id)source
  43. {
  44.     if (!mRunning && run)
  45.     {
  46.         mTimer = [[NSTimer scheduledTimerWithTimeInterval:mInterval
  47.                             target:self
  48.                             selector:@selector(drawAnother:)
  49.                             userInfo:NULL
  50.                             repeats:YES
  51.                       ] retain];
  52.         mRunning = YES;
  53.     }
  54.     else if (mRunning && !run)
  55.     {
  56.         // We're running and we've been told not to, so let's stop.
  57.         [mTimer invalidate];
  58.         [mTimer release];
  59.         mTimer = NULL;
  60.         mRunning = NO;
  61.     }
  62. }
  63.  
  64.  
  65.  
  66. - (void)setTimerInterval:(float)interval source:(id)source
  67. {
  68.     mInterval = interval;
  69.     
  70.     if (mRunning)
  71.         [self setTimerRunning:NO source:source];
  72.     
  73.     [self setTimerRunning:YES source:source];
  74. }
  75.  
  76.  
  77.  
  78. static float RandFloat(void)
  79. {
  80.     return ((float) rand() / (float) RAND_MAX);
  81. }
  82.  
  83.  
  84.  
  85. - (void)drawRandomBallInside:(const NSRect *)rect
  86. {
  87.     float    x, y;
  88.     float    minBallSize = 30.0;
  89.     float    maxBallSize = 100.0;
  90.     float    damp = .75;
  91.     NSBezierPath *oval;
  92.  
  93.     // Calculate where the ball should go.
  94.     
  95.     x = rect->origin.x + rect->size.width * RandFloat();
  96.     y = rect->origin.x + rect->size.height * RandFloat();
  97.  
  98.     // Set the current colour to a random RGB value.
  99.     [[NSColor colorWithDeviceRed:(RandFloat() * damp)
  100.                             green:(RandFloat() * damp)
  101.                             blue:(RandFloat() * damp)
  102.                             alpha:(fabs(RandFloat()) * damp)] set];
  103.  
  104.     // Now construct a bezier path for an circle and draw it.
  105.     oval = [NSBezierPath bezierPath];
  106.     [oval appendBezierPathWithOvalInRect:NSMakeRect(x, y,
  107.             minBallSize + (fabs(RandFloat()) * (maxBallSize - minBallSize)),
  108.             minBallSize + (fabs(RandFloat()) * (maxBallSize - minBallSize)))];
  109.     [oval fill];
  110. }
  111.  
  112.  
  113.  
  114. - (void)drawRect:(NSRect)rect
  115. {
  116.     // Do nothing.  In a normal view, you would update the visual
  117.     // representation of your view inside this method.  However, SillyBallView
  118.     // does not remember which balls that it's drawn, so there is nothing it
  119.     // can draw in this meathod.  Instead the drawing happens asynchronously
  120.     // inside the drawAnother: method.  See the notes in ReadMe.rtf for details.
  121. }
  122.  
  123.  
  124.  
  125. - (void)drawAnother:(id)timer
  126. {
  127.     NSRect visRect;
  128.  
  129.     // Lock focus on ourselves.  We need to do this because we're drawing
  130.     // outside of the context of NSView's drawRect: method.  This is relatively
  131.     // unusual behaviour for a view.  See the discussion of this in ReadMe.rtf.
  132.     
  133.     [self lockFocus];
  134.     
  135.     // Now draw a random ball inside the view.
  136.     visRect = [self visibleRect];
  137.     [self drawRandomBallInside:&visRect];
  138.     
  139.     // And unlock the focus.
  140.     [self unlockFocus];
  141.     
  142.     [[self window] flushWindow];
  143. }
  144. @end
  145.